/**
 * Polymorphism
 * 多态
 * 多态是指，针对某个类型的方法调用，其真正执行的方法取决于运行时期实际类型的方法
 * 在继承关系中，子类如果定义了一个与父类方法签名完全相同的方法，被称为覆写（Override）
 */
public class Polymorphism {

    public static void main(String[] args) {
        PersonPoly xiaoming = new PersonPoly();
        xiaoming.run();
        
        StudentPoly xiaowang = new StudentPoly();
        xiaowang.run("我跑了");

        // xiaoli的声明类型是Person,但是实际类型是Student
        // 那么xiaoli.run调用的是谁的run方法?
        // 运行得知,调用了Student.run
        // Java的实例方法调用是基于运行时的实际类型的动态调用，而非变量的声明类型。这个非常重要的特性在面向对象编程中称之为多态
        PersonPoly xiaoli = new StudentPoly();
        xiaoli.run(); //Student.run
    }
}

class PersonPoly {
    public void run() {
        System.out.println("Person.run");
    }
}
/**
 * 在子类中,覆写 run 方法
 * Override和Overload不同的是，如果方法签名如果不同，就是Overload，Overload方法是一个新方法；如果方法签名相同，并且返回值也相同，就是Override。
 */
class StudentPoly extends PersonPoly {
    // 加上@Override可以让编译器帮助检查是否进行了正确的覆写。希望进行覆写，但是不小心写错了方法签名，编译器会报错。
    @Override
    public void run() {
        System.out.println("Student.run");
    }

    // 使用和父类同样的方法名,参数不同,这叫"重载",不叫"覆写"
    public void run(String s) {
        System.out.println("Student.run" + s);
    }

    //写同样的方法,但是返回值不同,这样会报错,不能这样写
    // public int run(){
    //     System.out.println("Student.run int");
    //     return 10;
    // }
}